package org.cogaen.java2d.xml;

import java.awt.Image;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.cogaen.core.Core;
import org.cogaen.java2d.AnimationVisual;
import org.cogaen.java2d.ImageUtil;
import org.cogaen.java2d.SceneManager;
import org.cogaen.logging.LoggingService;
import org.cogaen.resource.ResourceManager;

public class AnimationXmlHandle extends XmlHandle {

	private static final String LOGGING_SOURCE = ResourceManager.LOGGING_SOURCE;
	private AnimationParser animationParser;
	
	public AnimationXmlHandle(String resourceName, String filename) {
		super(resourceName, filename, AnimationParser.createFilter(resourceName));
		this.animationParser = new AnimationParser();
	}

	@Override
	protected Object parseXml(Core core, XMLStreamReader parser) throws XMLStreamException {
		try {
			this.animationParser.parse(parser);
			return createAnimationVisual(core);
		} catch (ParseException e) {
			LoggingService logger = LoggingService.getInstance(core);
			logger.logWarning(LOGGING_SOURCE, "unable to load animation visual '" + getName() + "': " + e.getMessage());
			return new AnimationVisual(core, ImageUtil.createDummyImage(core), 1, 1, 1, 1);
		}		
	}

	private Object createAnimationVisual(Core core) {
		Image image;
		if (this.animationParser.getImageName() != null) {
			ResourceManager resMngr = ResourceManager.getInstance(core);
			if (resMngr.hasResource(this.animationParser.getImageName())) {
				image = (Image) resMngr.getResource(animationParser.getImageName());
			} else {
				LoggingService logger = LoggingService.getInstance(core);
				logger.logWarning(LOGGING_SOURCE, "referenced resource '" + animationParser.getImageName() + "' not found");
				image = ImageUtil.createDummyImage(core);
			}
		} else {
			LoggingService logger = LoggingService.getInstance(core);
			logger.logWarning(LOGGING_SOURCE, "no image specified for animation visual '" + getName() + "'");
			image = ImageUtil.createDummyImage(core);
		}

		double width = this.animationParser.getWidth();
		double height = this.animationParser.getHeight();
		
		if (width <= 0) {
			width = image.getWidth(null) / this.animationParser.getColumns();
		}
		
		if (height <= 0) {
			height = image.getHeight(null) / this.animationParser.getRows();
		}

		if (this.animationParser.getColumns() == 1 && this.animationParser.getRows() == 1) {
			LoggingService.getInstance(core).logWarning(SceneManager.LOGGING_SOURCE, "animation visual '" + getName() + "' hast got only one frame");
		}
		
		AnimationVisual animation = new AnimationVisual(core, image, this.animationParser.getColumns(), this.animationParser.getRows(), width, height);
		animation.setDisplayTime(this.animationParser.getDisplayTime());
		animation.setSequence(this.animationParser.getFirstFrame(), this.animationParser.getNumFrames());
		return animation;
	}

	@Override
	public Object getResource() {
		// Animations cannot share the same instance, because each instance
		// might render the animation at different positions.
		AnimationVisual animation = (AnimationVisual) super.getResource();
		return animation != null ? new AnimationVisual(animation) : null;
	}

}
